import json
import random
import re
import time

import requests
from django.shortcuts import render
from rest_framework import status
from rest_framework.generics import CreateAPIView, UpdateAPIView, ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated

from dingxiang_doctor.utils.baidu_api import baidu
from dingxiang_doctor.utils.myjwt import myjwt
from doctor.serial import History1Serializer, History2Serializer, History3Serializer
from doctor.models import History1, History2, History3
from user.models import User, OAuthUser, UserAuth
from user.serial import UserRegisterSerializer, SmsRegisterSerializer, OAuthUserSerializer, UserAuthSerializer
from user.service import send_sms
from dingxiang_doctor.utils.login_factory import Factory
from dingxiang_doctor.utils.myredis import r

import oss2
from django.core.files.storage import default_storage
from oss2 import Bucket
from dingxiang_doctor import settings
from mycelery.all_task.task import idcard


# Create your views here.
# 注册视图
class RegisterView(CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserRegisterSerializer


# 发送验证码视图
class SendSmsAPIView(APIView):
    def post(self, request):
        mobile = request.data.get("mobile", None)
        if mobile is None:
            return Response({"msg": "error", "data": "请输入电话号码"}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r"^1[3-9]\d{9}$", str(mobile)):
            return Response({"msg": "error", "data": "手机号格式错误"}, status=status.HTTP_400_BAD_REQUEST)
        if User.objects.filter(mobile=mobile):
            return Response({"msg": "error", "data": "该手机号已注册"}, status=status.HTTP_400_BAD_REQUEST)
        res = send_sms(mobile)
        if res:
            return Response({"msg": "ok", "data": "发送成功"})
        else:
            return Response({"msg": "error", "data": "验证码仍在有效期内，请勿频繁请求"},
                            status=status.HTTP_400_BAD_REQUEST)


# 使用验证码注册视图
class SmsRegisterView(CreateAPIView):
    queryset = User.objects.all()
    serializer_class = SmsRegisterSerializer


# 用户信息获取视图
class UserRetrieveAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        user = request.user
        data = {
            "id": user.id,
            "username": user.username,
            "mobile": user.mobile,
            "email": user.email,
            "gender": user.gender,
            "gender_display": user.get_gender_display(),
            "age": user.age,
            "avatar": "http://localhost:8000" + user.avatar.url
        }
        return Response({"msg": "ok", "data": data})


# 用户信息修改视图
class UserUpdateAPIView(UpdateAPIView):
    permission_classes = [IsAuthenticated]
    queryset = User.objects.all()
    serializer_class = UserRegisterSerializer


# 钉钉登录接口
class DingTalkLogin(APIView):
    def get(self, request):
        # from urllib.parse import quote
        # params = [
        #     f"redirect_uri={quote('http://127.0.0.1:8080/dingtalkCallback/')}",
        #     "response_type=code",
        #     "client_id=dingvcyxcogdqrstxgk7",
        #     "scope=openid",
        #     "prompt=consent"
        # ]
        # url = "https://login.dingtalk.com/oauth2/auth?" + ("&".join(params))
        # return Response({"url": url})

        # 获取第三方登录的种类
        types = request.query_params.get("types")
        factory = Factory()
        product = factory.create_factory(types)
        return Response({"url": product.get_url()})


# 钉钉回调接口
class DingTalkCallback(APIView):
    def get(self, request):
        authcode = request.query_params.get('authCode')
        types = request.query_params.get("types")
        print("types:", types)
        print("authcode:", authcode)
        # types = request.query_params.get("types")
        # print("authcode:", authcode)
        #
        # # 根据authCode获取用户accessToken
        # data = {
        #     "clientId": "dingvcyxcogdqrstxgk7",
        #     "clientSecret": "Pli_ZL5lJyl52u4Mkh6B0gUJtX-2ihDTwGvxB-bXYdukfDMbdqe0h2cMogqk8aXW",
        #     "code": authcode,
        #     "grantType": "authorization_code"
        # }
        # resp = requests.post('https://api.dingtalk.com/v1.0/oauth2/userAccessToken', json=data).json()
        # print("钉钉返回的userAccessToken：", resp)
        # accessToken = resp.get('accessToken')
        #
        # # 根据accessToken获取用户信息
        # headers = {"x-acs-dingtalk-access-token": accessToken}
        # resp = requests.get('https://api.dingtalk.com/v1.0/contact/users/me', headers=headers).json()
        # print("钉钉返回的用户信息：", resp)
        #
        # name = resp.get('nick')
        # uid = resp.get('openId')
        # mobile = resp.get('mobile')
        #
        # # 登录，写入三方登录表和用户表
        # # 判断该用户是否已经使用该第三方登录注册过
        # oauth = OAuthUser.objects.filter(uid=uid, type=1).first()
        # if not oauth:
        #     # 写入用户表
        #     # 手机号用户存在直接绑定,不存在注册新用户
        #     user = User.objects.filter(mobile=mobile).first()
        #     print(user)
        #     if not user:
        #         userinfo = {
        #             "name": name,
        #             "mobile": mobile,
        #             "password": "123456",
        #         }
        #         user_ser = UserRegisterSerializer(data=userinfo)
        #         if user_ser.is_valid():
        #             user = user_ser.save()
        #         else:
        #             return Response({"code": 10001, "msg": user_ser.errors})
        #     # 写入三方登录表
        #     oath_userinfo = {
        #         "type": 1,
        #         "token": accessToken,
        #         "uid": uid,
        #         "user": user.id
        #     }
        #     print(oath_userinfo)
        #     oath_ser = OAuthUserSerializer(data=oath_userinfo)
        #     if oath_ser.is_valid():
        #         print("11111111111111")
        #         oath_ser.save()
        #     else:
        #         return Response({"code": 10001, "msg": oath_ser.errors})
        # # 如果已经注册
        # else:
        #     user = oauth.user
        #     oauth.token = accessToken
        #     oauth.save()
        #
        # # 生成jwt token并返回前端
        # # payload = {"userid": user.id, "username": user.username, "exp": int(time.time()) + 60 * 60 * 2}
        # # token = myjwt.jwt_encode(payload)
        # # payload["exp"] = int(time.time() + 60 * 60 * 24 * 2)
        # # refreshToken = myjwt.jwt_encode(payload)
        # # query = [f"userid={payload['userid']}", f"username={payload['username']}", f"token={token}",
        # #          f"refreshToken={refreshToken}"]
        # return Response({"code": 200, "msg": "登录成功", "data": {"token": accessToken}})
        factory = Factory()
        product = factory.create_factory(types)
        data = product.callback(authcode=authcode)
        return Response(data)


# 上传图片到OSS，并返回OSS的url
class UploadImageAPIView(APIView):
    def post(self, request):
        if request.FILES.get('file'):
            file = request.FILES['file']
            destination = 'uploads/%s' % file.name
            auth = oss2.Auth(settings.OSS_ACCESS_KEY_ID, settings.OSS_ACCESS_KEY_SECRET)
            bucket = Bucket(auth, settings.OSS_ENDPOINT, settings.OSS_BUCKET_NAME)
            result = bucket.put_object(destination, file)
            print(result)
            signed_url = bucket.sign_url('GET', destination, 3600)
            index = signed_url.find("?")
            signed_url = signed_url[:index]
            return Response({'message': 'File uploaded successfully.', "url": signed_url})
        else:
            return Response({'error': 'No file provided.'}, status=400)


# 提交图片地址进行审核
class SubmitImageAPIView(APIView):
    def post(self, request):
        url = request.data.get("url")
        # 加入队列中
        r.list_push("baidu_url_list", url)
        # 异步验证
        # idcard.delay()
        return Response({'message': 'Image submitted for review.'})


# 前端轮询获取身份证验证信息
class GetInfo(APIView):
    def post(self, request):
        url = request.data.get("url")
        message = r.get_str(url)
        print("message:", message)
        if message:
            return Response({'message': message, "code": 200})
        else:
            return Response({'message': 'No message yet.', "code": 400})


# 向用户实名认证表中添加
class UserAuthCreateAPIView(CreateAPIView):
    permission_classes = [IsAuthenticated]
    queryset = UserAuth.objects.all()
    serializer_class = UserAuthSerializer

    def create(self, request, *args, **kwargs):
        user = self.request.user
        data = request.data
        idcard_url = data.get("url")
        print("data_message:", data.get("message"))
        message = json.loads(data.get("message"))
        the_message = json.loads(message)
        print("message:", the_message)
        print("type_message:", type(the_message))
        words_result = the_message.get("words_result")
        print("words_result:", words_result)
        idcard = the_message["words_result"]["公民身份号码"]["words"]
        name = the_message["words_result"]["姓名"]["words"]
        new_data = {"user": 6, "idcard_url": idcard_url, "idcard": idcard, "name": name}
        print(new_data)
        serializer = self.get_serializer(data=new_data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)


# 用户就医历史
class HistoryListAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        user = self.request.user
        if user.id % 3 == 0:
            history = History1.objects.filter(user=user)
            serializer = History1Serializer(history, many=True)
            return Response(serializer.data)
        elif user.id % 3 == 1:
            history = History2.objects.filter(user=user)
            serializer = History2Serializer(history, many=True)
            data = serializer.data
            return Response(serializer.data)
        else:
            history = History3.objects.filter(user=user)
            serializer = History3Serializer(history, many=True)
            return Response(serializer.data)


# websocket测试
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync


class Test(APIView):
    def get(self, request):
        # 获取信息
        # 查询数据库对比

        # update = AllDataConsumersUpdate()
        # update.all_active_visit_data()
        channel_layer = get_channel_layer()

        send_data = {"error": "1号大鹏温度太高", 'namelist': ['1001', '1002'],
                     'valuelist': [random.randint(100, 200), random.randint(100, 200)]}
        async_to_sync(channel_layer.group_send)(
            '2',  # 房间组名
            {
                'type': 'send_to_chrome',  # 消费者中处理的函数
                'data': send_data
            }
        )
        return Response({"code": 200, "msg": "更新数据成功"})
